/**
 * Copyright 2011 Mathieu Magnaudet
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package edu.enac.fileloader.service;

import java.io.FileOutputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import edu.enac.fileloader.exception.FileLoaderException;
import edu.enac.geoapp.model.Format;

/**
 * FTP implementation of the IFileLoader interface. This class
 * allows the user to load files located on a FTP server.  
 * @author mathieu
 * 
 */
public class FTPFileLoader implements IFileLoader {
	private Host host;
	private UserAccount account;
	private String destinationDirectory;

	/**
	 * Constructor 
	 * @param host the host to which establish a connection
	 * @param account a user account on the FTP server 
	 * @param destDirectory the directory where to put the loaded files
	 */
	public FTPFileLoader(Host host, UserAccount account, String destDirectory) {
		this.host = host;
		this.account = account;
		if (destDirectory.endsWith("/"))
			this.destinationDirectory = destDirectory;
		else
			this.destinationDirectory = destDirectory + "/";
	}

	/**
	 * @return the destinationDirectory
	 */
	public String getDestinationDirectory() {
		return destinationDirectory;
	}

	/**
	 * @param destinationDirectory the destinationDirectory to set
	 */
	public void setDestinationDirectory(String destinationDirectory) {
		this.destinationDirectory = destinationDirectory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see fr.enac.fileloader.service.IFileLoader#getFile(java.lang.String)
	 */
	@Override
	public boolean getFile(String pathname, String filename, Format f)
			throws FileLoaderException {
		String destFile = destinationDirectory + filename;
		FTPClient client;
		try {
			client = new FTPClient();

			// Connects to the FTP server
			client.connect(host.getHostname());

			// Checks the connection
			int reply = client.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				client.disconnect();
				throw new FileLoaderException("FTP server refused connection.");
			}

			// Sets the type (binary or default ascii) of the file to retrieve
			if (f.equals(Format.GEOTIFF) || f.equals(Format.PDF)
					|| f.equals(Format.GRIB) || f.equals(Format.JPEG2000)) {
				client.setFileType(FTP.BINARY_FILE_TYPE);
			}

			// logs in the server
			if (client.login(account.getUsername(), account.getPassword())) {

				// in case of firewall
				client.enterLocalPassiveMode();

				// Retrieves the file
				OutputStream output;
				output = new FileOutputStream(destFile);

				if (pathname != null && !pathname.isEmpty()) {
					client.changeWorkingDirectory(pathname);
				}
				client.retrieveFile(filename, output);

				// logout and close connection
				output.close();
				client.logout();
				client.disconnect();
			} else {
				throw new FileLoaderException("Unable to log in ftp server");
			}

		} catch (Exception e) {
			e.printStackTrace();
			throw new FileLoaderException(e.getMessage());
		}

		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.enac.fileloader.service.IFileLoader#setHost(fr.enac.fileloader.service
	 * .Host)
	 */
	@Override
	public void setHost(Host newHost) {
		this.host = newHost;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "FTPFileLoader [account=" + account + ", destinationDirectory="
				+ destinationDirectory + ", host=" + host + "]";
	}

}
